Research and Experimentation: Implementing New Features in OBS
Date: November 30th, 2025
Introduction
In this document, we want to detail how we carried out an experiment to understand the internal workings of OBS, its public API, and the possibilities offered by the software.
Documentation
During the first part of this experiment, we attempted to understand the internal workings of OBS and define the main development steps we would need to perform to achieve our goals.
However, the documentation proved to be very brief and focuses mainly on certain technical aspects and specific functions, without really giving a global overview of how the project works and the interactions between the different components.
Based on this observation, we decided to prototype the implementation of the module using the public APIs provided by libOBS to better understand its operation and the relationships between the different components.
To complete our understanding, we also decided to study two third-party plugins for OBS:
- Multiple RTMP
- Source Record
These plugins, although not doing exactly what we are trying to achieve, allowed us to understand the functions used to create the objects necessary for video encoding, source enumeration, and streaming using the RTMP protocol.
Experimentation
To put into practice and understand the overall architecture of the project, we conducted an experiment involving the recording of a video file using the libOBS API within a module.
We therefore started by attempting to make a custom implementation of a video output object obs_output_t by creating our own version, as well as our own obs_service_t service.
In OBS, an output is an object that allows configuring the output type (to a file, stream, etc.) to which one or more encoders can be attached.
This output can work in tandem with an obs_service_t which implements the abstractions necessary for communication with third-party services, for example to retrieve stream keys, authenticate a user, and interact with a streaming platform.
Steps
We detail here the main steps for using the public API provided by libOBS.
OBS uses a modular architecture that divides the majority of its features into modules (shared libraries) loaded at OBS startup, in order to create a module to record a simple video.
Steps to create an OBS module:
- Structure
- Create a folder and add a minimal CMakeLists.txt in the
pluginsfolder; the CMakeLists must include the OBS API libraries:OBS::libobs,OBS::frontend-api, and$<$<PLATFORM_ID:Windows>:OBS::w32-pthreads>for Windows compatibility.
- Create a folder and add a minimal CMakeLists.txt in the
- Mandatory methods:
- Two methods must be implemented to register the module with OBS:
obs_module_load(void): This is the entry point of the module; the module must allocate its internal structures and data it will need during execution.void obs_module_unload(void): Unloading the module
- Frontend event callback
- To continue the experiment, we add a callback when events are generated by the user interface using the function:
obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data), with the callback and the pointer to the data allocated by the module as parameters.
- To continue the experiment, we add a callback when events are generated by the user interface using the function:
- Creating an output object
- The output object represents the output to a file or stream. Here we simply record to a file:
obs_output_create("mp4_output", "FOV mp4 video", NULL, NULL);- Configure the output (using the
obs_data_set_stringfunction: path, directory, format, extension)
- Creating an audio encoder
obs_audio_encoder_create("ffmpeg_aac", "FOVAudio", NULL, 0, NULL);
- Creating a video encoder
obs_video_encoder_create("obs_x264", "FOVSource", NULL, NULL);
- Update the parameters of the audio and video encoders (scaled_size, framerate divisor)
- Pass the main video source to the video encoder
obs_encoder_set_video(video_encoder, obs_get_video()); - Pass the main audio source to the audio encoder
obs_encoder_set_audio(audio_encoder, obs_get_audio()); - Link the encoders to the output:
obs_output_set_audio_encoder(audio_encoder, audio_encoder, 0);obs_output_set_video_encoder(video_encoder, video_encoder);
- Initialize the encoders linked to the output
obs_output_initialize_encoders(fov_app.fov_out, 0);
- Start the output
obs_output_start(fov_app.fov_out);